package com.zyd.util;

import com.google.common.base.Splitter;
import com.zyd.io.page.OperateKey;
import com.zyd.io.page.SearchKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

public class SqlUtils {

    private static final Logger logger = LoggerFactory.getLogger(SqlUtils.class);


    private static final Splitter SPLITTER = Splitter.on(',').omitEmptyStrings().trimResults();

    /**
     * SQL 添加like
     *
     * @param str
     */
    public static String andLike(String str) {
        return "%" + str + "%";
    }


    public static String addPage(String sql, int page, int pageSize) {
        return sql += " limit " + (page - 1) * pageSize + "," + pageSize;
    }

    public static String andQuote(String sql) {
        return "\'" + sql + "\'";
    }

    /**
     * 生成多条件查询的语句
     * @param searchKeys
     * @return
     */
    public static String addMultiCondition(List<SearchKey> searchKeys) {
        StringBuilder sql = new StringBuilder();
        for (SearchKey searchKey : searchKeys) {
            sql.append("  and " + searchKey.getName() + " " + searchKey.getOperate() + " ");
            if (searchKey.getOperate().equalsIgnoreCase(OperateKey.LIKE)) {
                sql.append("\'" + SqlUtils.andLike(searchKey.getValue()) + "\'");
            } else {
                //支持 =、>、<、!=、like、in、notin
                sql.append("\'" + searchKey.getValue() + "\'");
            }
        }
        return sql.toString();
    }

    public static String addIn(String areaids) {
        StringBuilder sb = new StringBuilder();
        List<String> value = SPLITTER.splitToList(areaids);
        for (String s : value) {
            sb.append("\"" + s + "\"");
            sb.append(",");
        }

        String ret = sb.toString();
        if (ret.endsWith(",")) {
            ret = ret.substring(0, ret.length() - 1);
        }
        return ret;
    }

    /**
     * 生成多条件查询的语句
     * @param searchKeys
     * @return
     */
    public static String addMultiCondition(List<SearchKey> searchKeys, FieldMapping mapping) {
        StringBuilder sql = new StringBuilder();
        for (SearchKey searchKey : searchKeys) {
            sql.append("  and " + mapping.getMapping(searchKey.getName()) + " " + searchKey.getOperate() + " ");
            if (searchKey.getOperate().equalsIgnoreCase(OperateKey.LIKE)) {
                sql.append("\'" + SqlUtils.andLike(searchKey.getValue()) + "\'");
            } else {
                //支持 =、>、<、!=、like、in、notin
                sql.append("\'" + searchKey.getValue() + "\'");
            }
        }
        return sql.toString();
    }

    /**
     * 数据库查询结果mapping到bean中
     *
     * @return
     */
    public static <T> T mappingToBean(ResultSet resultSet, Class<T> clazz) {
        try {
            T ret = clazz.newInstance();
            List<Field> fields = getAllFieldsList(clazz);
            for (Field field : fields) {
                Class<?> fieldType = field.getType();
                if (fieldType == String.class) {
                    doStringMapping(field, ret, resultSet);
                } else if (fieldType == Integer.class) {
                    doIntMapping(field, ret, resultSet);
                } else if (fieldType == BigDecimal.class) {
                    doBigDecimalMapping(field, ret, resultSet);
                }
            }
            return ret;
        } catch (Exception e) {
            logger.error("" + e.getMessage());
        }
        return null;
    }

    private static void doStringMapping(Field field, Object obj, ResultSet resultSet) {
        try {
            field.setAccessible(true);
            field.set(obj, resultSet.getString(field.getName()));
        } catch (Exception e) {
            logger.warn("" + e.getMessage());
        }
    }

    private static void doIntMapping(Field field, Object obj, ResultSet resultSet) {
        try {
            field.setAccessible(true);
            field.set(obj, resultSet.getInt(field.getName()));
        } catch (Exception e) {
            logger.warn(""+ e.getMessage());
        }
    }

    private static void doBigDecimalMapping(Field field, Object obj, ResultSet resultSet) {
        try {
            field.setAccessible(true);
            field.set(obj, resultSet.getBigDecimal(field.getName()));
            //2018-11-03 只做提示
        } catch (Exception e) {
            logger.warn("" + e.getMessage());
        }
    }

    public static List<Field> getAllFieldsList(final Class<?> cls) {
        final List<Field> allFields = new ArrayList<Field>();
        Class<?> currentClass = cls;
        while (currentClass != null) {
            final Field[] declaredFields = currentClass.getDeclaredFields();
            for (final Field field : declaredFields) {
                allFields.add(field);
            }
            currentClass = currentClass.getSuperclass();
        }
        return allFields;
    }
}
